<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>发布订阅模式</title>
  </head>
  <body>
    <div class="container">
      <button onclick="emit()">发布订阅</button>
    </div>
    <script type="text/javascript">
      //它得需要一个全局对象 也就是当前上下文
      const context = {};
      //在程序初始化的时候 需要添加对应的 观察者/订阅者
      //我们知道 前端对象 存储方式是以对象方式 对应一个key 跟对应的value 其实就是一个实体的javabean
      // 定义订阅 在对象里面定义一个数组
      function subscribe(eventName, cb) {
        (context[eventName] || (context[eventName] = [])).push(cb);
      }

      //把所需要的 订阅者对象 压入当前上下文对象的订阅的列表存储 =>其实就是添加观察者/订阅者对象
      function publish(eventName) {
        const cbs = context[eventName] || [];
        // 用for of 遍历 它是异步的
        for (cb of cbs) {
          cb(); //调用回调函数
        }
      }

      //产生订阅
      subscribe('baseChange', () => {
        console.log('callback触发');
        document.body.style.backgroundColor = 'red';
      });

      function emit() {
        console.log('订阅对象', context);
        //调用订阅者的回调
        publish('baseChange');
      }
    </script>
  </body>
</html>
